package com.wuge.cart.service.ServiceImpl;

import com.alibaba.fastjson.JSON;
import com.wuge.cart.Feign.ProductFeign;
import com.wuge.cart.interceptor.UserInterceptor;
import com.wuge.cart.service.CartService;
import com.wuge.cart.to.UserInfoTo;
import com.wuge.cart.vo.CartItemVo;
import com.wuge.cart.vo.SkuInfoEntity;
import com.wuge.common.utils.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Service
public class CartServiceImpl implements CartService {


    @Autowired
    private StringRedisTemplate redisTemplate;
    @Resource
    private ProductFeign productFeign;
    private  static String REDIS_CART_PRE="cart:";
    @Resource
    private ThreadPoolExecutor threadPoolExecutor;
    @Override
    public void deleteItem(Long skuId) {
        BoundHashOperations<String, Object, Object> cart = getCart();
        cart.delete(skuId.toString());

    }
    @Override
    public void changeCheck(Long skuId, Integer check) {
        BoundHashOperations<String, Object, Object> cart = getCart();
        String sku = (String)cart.get(skuId.toString());
        CartItemVo cartItemVo = JSON.parseObject(sku, CartItemVo.class);
        cartItemVo.setCheck(check==1);
        cart.put(skuId.toString(),JSON.toJSONString(cartItemVo));
    }

    @Override
    public List<CartItemVo> currentlist() {
        List<CartItemVo> list = list();
        List<CartItemVo> cartItemVos = list.stream().filter((cartItemVo -> {
            return cartItemVo.getCheck();
        })).map(cartItemVo -> {
            cartItemVo.setPrice(productFeign.getCurrentPrice(cartItemVo.getSkuId()));
            return cartItemVo;
        }).collect(Collectors.toList());
        return cartItemVos;
    }


    @Override
    public void countItem(Long skuId, Integer num) {
        BoundHashOperations<String, Object, Object> cart = getCart();
        String sku = (String)cart.get(skuId.toString());
        CartItemVo cartItemVo = JSON.parseObject(sku, CartItemVo.class);
        cartItemVo.setCount(num);
        cart.put(skuId.toString(),JSON.toJSONString(cartItemVo));
    }

    @Override
    public CartItemVo addSku(Long skuId, Integer num) {

//        异步任务优化
//        绑定某个用户的购物车
        BoundHashOperations<String, Object, Object> cart = getCart();
//        调用商品模块获取sku信息
        CartItemVo cartItemVo=new CartItemVo();
        CompletableFuture<Void> future1 = CompletableFuture.runAsync(() -> {
            R sku = productFeign.getSku(skuId);
            Object skuInfo = sku.get("skuInfo");
            SkuInfoEntity skuInfoEntity = JSON.parseObject(JSON.toJSONString(skuInfo), SkuInfoEntity.class);
            cartItemVo.setPrice(skuInfoEntity.getPrice());
            cartItemVo.setImage(skuInfoEntity.getSkuDefaultImg());
            cartItemVo.setTitle(skuInfoEntity.getSkuTitle());
            cartItemVo.setSkuId(skuId);

        }, threadPoolExecutor);

        CompletableFuture<Void> future2 = CompletableFuture.runAsync(() -> {
            //调用商品模块获取属性信息
            List<String> attrStr = productFeign.getAttrStr(skuId);
            cartItemVo.setSkuAttrValues(attrStr);
        }, threadPoolExecutor);

//    判断购物车中是否有该商品
        String product = (String)cart.get(skuId.toString());
        if (StringUtils.isEmpty(product)){
            cartItemVo.setCount(num);
        }else{
            CartItemVo itemVo = JSON.parseObject(product, CartItemVo.class);
            cartItemVo.setCount(itemVo.getCount()+num);
        }
        CompletableFuture<Void> voidCompletableFuture = CompletableFuture.allOf(future1, future2);
        try {
            voidCompletableFuture.get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        //将购物车商品添加到redis中
        cart.put(skuId.toString(),JSON.toJSONString(cartItemVo));
        return cartItemVo;
    }
    public BoundHashOperations<String, Object, Object> getCart(){
        UserInfoTo userInfoTo = UserInterceptor.localUser.get();
        String key;
        if (userInfoTo.getTempUser()){
            key=REDIS_CART_PRE+userInfoTo.getUserKey();
        }
        else{
            key=REDIS_CART_PRE+userInfoTo.getUserId();
        }
        BoundHashOperations<String, Object, Object> stringObjectObjectBoundHashOperations = redisTemplate.boundHashOps(key);
        return stringObjectObjectBoundHashOperations;
    }

    @Override
    public CartItemVo getCartItem(Long skuId) {
        String cartItem = (String)getCart().get(skuId.toString());
        return JSON.parseObject(cartItem,CartItemVo.class);
    }

    @Override
    public List<CartItemVo> list() {
        UserInfoTo userInfoTo = UserInterceptor.localUser.get();
//        当用户未登录的情况下
        if (userInfoTo.getTempUser()){
            return getCartItemVos();
        }else{
            List<CartItemVo> cartItemVos = getCartItemVos();
//            获取未登录时的购物车信息合并购物车
            String key;
            key=REDIS_CART_PRE+userInfoTo.getUserKey();
            BoundHashOperations<String, Object, Object> cart = redisTemplate.boundHashOps(key);
            List<Object> values = cart.values();
            if (values.size()==0){
               return cartItemVos;
            }
            List<CartItemVo> itemVoList = values.stream().map((obj) -> {
                String cartItem = (String) obj;
                CartItemVo cartItemVo = JSON.parseObject(cartItem, CartItemVo.class);
                return cartItemVo;
            }).collect(Collectors.toList());
        itemVoList.forEach((item)->{
            addSku(item.getSkuId(),item.getCount());
        });
        redisTemplate.delete(key);
        return getCartItemVos();
        }

        }




    private List<CartItemVo> getCartItemVos() {
        BoundHashOperations<String, Object, Object> cart = getCart();
        List<Object> values = cart.values();
        if (values.size()==0){
            return null;
        }
        List<CartItemVo> itemVoList = values.stream().map((obj) -> {
            String cartItem = (String) obj;
            CartItemVo cartItemVo = JSON.parseObject(cartItem, CartItemVo.class);
            return cartItemVo;
        }).collect(Collectors.toList());
        return itemVoList;
    }
}
